<template>
    <div>
        {{ url }}
        <div class="content">
            <div id="myIframe" style="max-width: 700px; min-height: 550px; position: relative; margin: 0 auto">
                <pdf id="pdfBox" :page="pageNum" :src="url" @progress="loadedRatio = $event"
                    @num-pages="totalPages = $event"></pdf>
            </div>
            <el-button v-if="false" type="primary" @click="downFile" plain style="width: 300px">保存并下载pdf</el-button>
        </div>
        <span slot="footer" class="dialog-footer">
            <div class="btnGroup" v-if="totalPages">
                <div class="pageNum">{{ pageNum }} / {{ totalPages }}</div>
                <el-button-group>
                    <el-button round plain type="primary" icon="el-icon-arrow-left" size="mini"
                        @click="prePage">上一页</el-button>
                    <el-button round plain type="primary" size="mini" @click="nextPage">下一页<i
                            class="el-icon-arrow-right el-icon--right"></i></el-button>
                </el-button-group>
            </div>
        </span>
    </div>
</template>
  
<script>
/* npm i vue-pdf --save
npm install --save @pdf-lib/fontkit
npm i pdf-lib --save
*/

import pdf from "vue-pdf";
import { degrees, PDFDocument, rgb, StandardFonts } from "pdf-lib";
import fontkit from "@pdf-lib/fontkit"; //为 pdf-lib 加载自定义字体的工具

export default {
    props: ["url"],
    components: {
        pdf,
    },
    data() {
        return {
            pageNum: 1, //显示第一页
            loadedRatio: 0, // 当前页面的加载进度，范围是0-1 ，等于1的时候代表当前页已经完全加载完成了
            totalPages: 0, //pdf总页数
            fileUrl: "XXXXX.pdf",
        };
    },

    mounted() {
        this.getPageNum();
    },
    methods: {
        // 获取PDF总页数
        getPageNum() {
            let loadingTask = pdf.createLoadingTask(this.fileUrl);
            loadingTask.promise
                .then((pdf) => {
                    this.totalPages = pdf.numPages;
                    this.$nextTick(() => {
                        this.setWatermarkContent();
                    });
                })
                .catch((err) => {
                    this.$message.warning("pdf加载失败");
                });
        },
        // 上一页
        prePage() {
            let page = this.pageNum;
            page = page > 1 ? page - 1 : this.totalPages;
            this.pageNum = page;
            window.scrollTo(0, 0);
        },

        // 下一页
        nextPage() {
            let page = this.pageNum;
            page = page < this.totalPages ? page + 1 : 1;
            this.pageNum = page;
            window.scrollTo(0, 0);
        },

        setWatermarkContent() {
            // 1.创建canvas容器（用于显示水印文字）
            let ele = document.createElement("canvas");
            ele.width = 250;
            ele.height = 200;
            let objmsg = {
                canvas: ele,
                fontText: "张三-2023-01-01", // String
                fontSize: 20,
                fontFamily: "microsoft yahei",
                fontcolor: "#dadbdc", //字体颜色   默认 #dadbdc
                rotate: 25, //旋转角度   数字类型
                textAlign: "left", //水印文字居中方式:left center right  默认 left
            };
            // 2.创建水印canvas
            this.createWaterMark(objmsg);
            // 2.将水印canvas遮罩层定位到pdf容器中
            this.drawWaterMark(ele);
        },
        // 创建canvas水印图片
        createWaterMark({ canvas, fontText, fontFamily = "microsoft yahei", fontSize = 30, fontcolor = "#dadbdc", rotate = 30, textAlign = "left" }) {
            let ctx = canvas.getContext("2d");
            ctx.font = `${fontSize}px ${fontFamily}`;
            ctx.rotate((-rotate * Math.PI) / 180);
            ctx.fillStyle = fontcolor;
            ctx.textAlign = textAlign;
            ctx.textBaseline = "Middle";
            ctx.fillText(fontText, canvas.width / 6, canvas.height / 2);
        },
        // 给pdf增加水印遮罩层
        drawWaterMark(ele) {
            let div = document.createElement("div");
            div.style.pointerEvents = "none";
            div.style.top = "0";
            div.style.left = "0px";
            div.style.position = "absolute";
            div.style.background = "url(" + ele.toDataURL("image/png") + ") left top repeat";
            let width = document.getElementById("pdfBox").clientWidth || 700;
            let height = document.getElementById("pdfBox").clientHeight || 700;
            div.style.width = width + "px";
            div.style.height = height + "px";
            document.getElementById("myIframe").appendChild(div);
        },

        // PDF 下载
        async downFile() {
            /*2.获取pdf文件的arrarybuffer文件流
             可请求后台接口返回的base64文件流，然后转成arrayBuffer类型
             可访问前端项目中的本地文件，不能直接访问服务器链接文件，会有跨域问题*/
            try {
                // 1.通过url获取pdf文件的arrarybuffer文件流
                const existingPdfBytes = await fetch(this.fileUrl).then((res) => res.arrayBuffer());
                // 2.将arraybuffer数据转成pdf文档
                const pdfDoc = await PDFDocument.load(existingPdfBytes);
                // 3.1  内置字体（不支持中文）, 如果水印中不包含中文可直接用内置字体(不支持中文)
                // const fontkitFile = await pdfDoc.embedFont(StandardFonts.Helvetica);
                // 3.2 自定义字体，如不需要使用自定义字体可以将这一段全部注释掉，也不用下载自定义字体文件和自定义字体工具fontkit
                // 将自己下载好的.ttf文件放置项目中，然后访问文件路径(不支持访问本地文件)
                const fontBytes = await fetch("/fonts/SourceHanSansCN-Normal.ttf").then((res) => res.arrayBuffer());
                pdfDoc.registerFontkit(fontkit); // 自定义字体挂载、fontkit为自定义字体注册工具
                const fontkitFile = await pdfDoc.embedFont(fontBytes);
                //  4. 为每页pdf添加文字水印
                const pages = pdfDoc.getPages();
                for (let i = 0; i < pages.length; i++) {
                    const noPage = pages[i];
                    const { width, height } = noPage.getSize();
                    for (let i = 0; i < 10; i++) {
                        for (let j = 0; j < 3; j++) {
                            noPage.drawText('张三-2023-01-01', {
                                x: 230 * j,
                                y: (height / 4) * i,
                                size: 20,
                                font: fontkitFile, //字体（内置/自定义）
                                color: rgb(0.46, 0.53, 0.6),
                                rotate: degrees(45),
                                opacity: 0.3,
                            });
                        }
                    }
                }
                //5. 保存pdf文件的unit64Arrary文件流
                const pdfBytes = await pdfDoc.save();
                this.saveByteArray("水印PDF.pdf", pdfBytes);
            } catch (error) {
                this.$message.warning("文件下载失败！");
            }
        },
        // 下载文件
        saveByteArray(fileName, byte) {
            var blob = new Blob([byte], { type: "application/pdf" });
            var link = document.createElement("a");
            link.href = window.URL.createObjectURL(blob);
            var fileName = reportName;
            link.download = fileName;
            link.click();
        },
    },
};
</script>
  